import { Graph, Shape } from "@antv/x6";
import { LoopJupge } from "./loopJupge";
export class X6Graph {
  /*
  初始化x6画布
   */
  constructor(id) {
    this.id = id;
    this.graphParam = this.initGraphParams();
  }

  initGraphParams() {
    const params = {
      container: this.id,
      background: {
        color: "#f9fbfd",
      },
      autoResize: true,
      grid: {
        size: 10,
        visible: true,
        type: "mesh", // 'dot' | 'fixedDot' | 'mesh'
        args: {
          color: "#5F708A", // 网格线/点颜色
          thickness: 0.1, // 网格线宽度/网格点大小
        },
      },
      panning: true,
      keyboard: true,
      mousewheel: {
        enabled: true,
        modifiers: ["ctrl", "meta"],
      },
      nodeStyle: {
        resizable: false,
        strokeWidth: 1,
      },
    };
    return params;
  }

  modGraph(obj) {
    return new Graph(obj);
  }

  createChoreographer() {
    /*
    模组编排Graph
     */
    const enabled = {
      enabled: true,
    };
    this.graphParam.selecting = enabled;
    this.graphParam.embedding = enabled;
    this.graphParam.clipboard = enabled;
    const connecting = {
      anchor: "center",
      connectionPoint: "anchor",
      allowBlank: false,
      highlight: true,
      allowLoop: false,
      snap: true,
      connector: { name: "curve" },
      createEdge() {
        return new Shape.Edge({
          attrs: {
            line: {
              stroke: "#00bbec",
              strokeWidth: 1.8,
              sourceMarker: {
                tagName: "circle",
                r: 6,
                cx: 6,
                fill: "#00bbec",
                stroke: "#00bbec",
              },
              targetMarker: {
                name: "block",
                args: {
                  size: "6",
                },
              },
            },
          },
          router: {
            name: "manhattan",
          },
          zIndex: 0,
        });
      },
      validateMagnet({ magnet }) {
        return magnet.getAttribute("port-group") !== "in";
      },
      validateConnection({
        sourceView,
        targetView,
        sourceMagnet,
        targetMagnet,
      }) {
        if (!sourceMagnet || sourceMagnet.getAttribute("port-group") === "in") {
          return false;
        }
        // 只能连接到输入链接桩
        if (!targetMagnet || targetMagnet.getAttribute("port-group") !== "in") {
          return false;
        }
        // 已被连接的端口不再可选
        const sourcePortId = sourceMagnet.getAttribute("port");
        const targetPortId = targetMagnet.getAttribute("port");
        const targetCell = targetView.cell;
        const sourceCell = sourceView.cell;
        const targetPort = targetCell.getPort(targetPortId);
        const sourcePort = sourceCell.getPort(sourcePortId);
        // 已被连接
        if (
          targetPort &&
          targetPort.connected
        ) {
          return false;
        }
        return true;
      },
    };
    const highlighting = {
      magnetAvailable: {
        name: "stroke",
        args: {
          padding: 6,
          attrs: {
            "stroke-width": 8,
            stroke: "#81C784",
          },
        },
      },
    };
    this.graphParam.highlighting = highlighting;
    this.graphParam.connecting = connecting;
    return this.modGraph(this.graphParam);
  }
}

export class EventListener {
  constructor(graph) {
    this.graph = graph;
  }

  connectedEvent() {
    /*
    <连线事件监听>
    边连接时触发的事件：将节点上已连接的连接桩设置未已连接
     */
    this.graph.on("edge:connected", (args) => {
      const node = args.currentCell;
      const elem = args.currentMagnet;
      const portId = elem.getAttribute("port");
      const nodePort = node.getPort(portId);
      // 成环判断
      const allEdges = this.graph.getEdges();
      const edgesData = [];
      allEdges.forEach(function (edge, index) {
        const SourceTarget = {
          source: edge.getSource().cell,
          target: edge.getTarget().cell,
        };
        const temporaryData = JSON.parse(JSON.stringify(SourceTarget));
        edgesData.push(temporaryData);
      });
      const isLoop = LoopJupge(edgesData);
      if (isLoop) {
        console.log("该线导致成环，请重新连线！");
        this.graph.removeEdge(args.edge);
      } else {
        // 触发 port 重新渲染
        node.setPortProp(portId, "connected", true);
      }
    });
  }

  removedEdgeEvent() {
    /*
    <移除边事件监听>
    边移除时触发的事件：将节点连接桩设置为初始值
     */
    this.graph.on("edge:removed", (args) => {
      console.log("移除边");
    });
  }

  contextmenuEvent() {
    this.graph.on("node:contextmenu", ({ cell, view }) => {
      const oldText = cell.attr("text/textWrap/text");
      const elem = view.container.querySelector(".x6-edit-text");
      if (elem == null) {
        return;
      }
      cell.attr("text/style/display", "none");
      if (elem) {
        elem.style.display = "";
        elem.contentEditable = "true";
        elem.innerText = oldText;
        elem.focus();
      }
      const onBlur = () => {
        cell.attr("text/textWrap/text", elem.innerText);
        cell.attr("text/style/display", "");
        elem.style.display = "none";
        elem.contentEditable = "false";
      };
      elem.addEventListener("blur", () => {
        onBlur();
        elem.removeEventListener("blur", onBlur);
      });
    });
  }

  mouseenterEdgeEvent() {
    this.graph.on("edge:mouseenter", ({ edge }) => {
      edge.addTools([
        "target-arrowhead",
        {
          name: "button-remove",
          args: {
            distance: -30,
          },
        },
      ]);
    });
  }

  mouseleaveEdgeEvent() {
    this.graph.on("edge:mouseleave", ({ edge }) => {
      edge.removeTools();
    });
  }
}
